#include<stdio.h>
#include<malloc.h>
#include<stdbool.h>//bool:true\false
#include "Circular_queue.h"

/*初始化循序循环队列*/
S_Queue_t* InitQueue(void)
{
    S_Queue_t *queue = (S_Queue_t *)malloc(sizeof(S_Queue_t));
    if (!queue)
    {
        return NULL;
    }
    
    queue->base = (ElemType *)malloc(sizeof(ElemType) * MAX_QUEUE_SIZE);
    if (!queue->base)
    {
        free(queue);
        return NULL;
    }
    
    queue->front = 0;
    queue->rear = 0;
    return queue;
}

/*销毁队列*/
void DestroyQueue(S_Queue_t **queue)
{
    if (!(*queue))
    {
        return;
    }
    
    free((*queue)->base);
    free(*queue);
    *queue = NULL;
    
}

/*队列是否为空*/
bool IsQueueEmpty(S_Queue_t *queue)
{
    if (!queue)
    {
        exit(-1);
    }
    
    if (queue->front == queue->rear)
    {
        printf("队列为空\n");
        return true;
    }
    
    return false;
}

/*队列是否满*/
bool IsQueueFUll(S_Queue_t *queue)
{
    if (!queue)
    {
        exit(-1);
    }
    
    return ((queue->rear + 1) % MAX_QUEUE_SIZE == queue->front);
}

/*入队*/
S_Queue_t* enQueue(S_Queue_t *queue,ElemType data)
{
    if (IsQueueFUll(queue))
    {
        return queue;
    }

    queue->base[queue->rear ++] = data;
    printf("入队元素为%d\n",(int)data);
    return queue;
}

/*出队*/
ElemType deQueue(S_Queue_t *queue)
{
    if (IsQueueEmpty(queue))
    {
        exit(-1);
    }

    ElemType data = queue->base[queue->front ++];
    printf("出队元素为%d\n",(int)data);
    return data;
}


/*取队首元素*/
ElemType getHead(S_Queue_t *queue)
{
    if (IsQueueEmpty(queue))
    {
        exit(-1);
    }
    
    ElemType data = queue->base[queue->front];
    printf("队首元素为%d\n",data);
    return data;
}

/*取队尾元素*/
ElemType getTail(S_Queue_t *queue)
{
    if (IsQueueEmpty(queue))
    {
        exit(-1);
    }
    
    int index = queue->rear - 1;
    ElemType data = queue->base[index];
    printf("队尾元素为%d\n",data);
    return data;
}

S_Queue_t *queue = NULL;
int main(int argc, char const *argv[])
{
    queue = InitQueue();

    enQueue(queue,20);
    getHead(queue);
    getTail(queue);
    enQueue(queue,20);
    enQueue(queue,20);
    enQueue(queue,30);
    enQueue(queue,40);
    enQueue(queue,80);
    getHead(queue);
    getTail(queue);
    deQueue(queue);
    deQueue(queue);
    deQueue(queue);
    deQueue(queue);
    deQueue(queue);
    deQueue(queue);
    deQueue(queue);
    return 0;
}
